package br.com.advocacia.faces;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;

import br.com.advocacia.entidade.AreaProcessual;
import br.com.advocacia.entidade.Comarca;
import br.com.advocacia.entidade.FaseProcesso;
import br.com.advocacia.entidade.Foro;
import br.com.advocacia.entidade.Instancia;
import br.com.advocacia.entidade.Processo;
import br.com.advocacia.entidade.Rito;
import br.com.advocacia.entidade.SituacaoProcesso;
import br.com.advocacia.entidade.TipoAcao;
import br.com.advocacia.entidade.Vara;
import br.com.advocacia.logica.contract.DefaultLogicaContract;
import br.com.advocacia.logica.contract.ProcessoLogicaContract;
import br.com.advocacia.util.DataUtil;
import br.com.advocacia.util.FacesUtil;
import br.com.advocacia.util.StringUtil;

@ManagedBean(name="processoFaces")
@ViewScoped
public class ProcessoFaces extends FacesUtil {
	
	private static final long serialVersionUID = 1L;

	@ManagedProperty(value = "#{logicaDefault}")
	private DefaultLogicaContract<Processo> logicaProcesso;
	
	@ManagedProperty(value = "#{logicaDefault}")
	private DefaultLogicaContract<TipoAcao> logicaTipoAcao;
	
	@ManagedProperty(value = "#{logicaDefault}")
	private DefaultLogicaContract<Vara> logicaVara;
	
	@ManagedProperty(value = "#{logicaDefault}")
	private DefaultLogicaContract<Comarca> logicaComarca;
	
	@ManagedProperty(value = "#{logicaDefault}")
	private DefaultLogicaContract<Rito> logicaRito;
	
	@ManagedProperty(value = "#{logicaDefault}")
	private DefaultLogicaContract<Foro> logicaForo;
	
	@ManagedProperty(value = "#{logicaDefault}")
	private DefaultLogicaContract<AreaProcessual> logicaAreaProcessual;
	
	@ManagedProperty(value = "#{logicaDefault}")
	private DefaultLogicaContract<FaseProcesso> logicaFaseProcesso;
	
	@ManagedProperty(value = "#{logicaDefault}")
	private DefaultLogicaContract<SituacaoProcesso> logicaSituacaoProcesso;
	
	@ManagedProperty(value = "#{logicaDefault}")
	private DefaultLogicaContract<Instancia> logicaInstancia;
	
	@ManagedProperty(value = "#{processoLogica}")
	private ProcessoLogicaContract processoLogica;
	
	private Processo processo = new Processo();
	private List<Processo> listaProcesso = new ArrayList<>();
	
	private List<TipoAcao> listaTipoAcao = new ArrayList<>();
	private List<Vara> listaVara = new ArrayList<>();
	private List<Comarca> listaComarca = new ArrayList<>();
	private List<Rito> listaRito = new ArrayList<>();
	private List<Foro> listaForo = new ArrayList<>();
	private List<AreaProcessual> listaAreaProcessual = new ArrayList<>();
	private List<FaseProcesso> listaFaseProcesso = new ArrayList<>();
	private List<SituacaoProcesso> listaSituacaoProcesso = new ArrayList<>();
	private List<Instancia> listaInstancia = new ArrayList<>();
	
	
	/** CAMPOS DE PESQUISA */
	private String numeroProcesso;
	
	@PostConstruct
	public void init() {
		this.popularComboAreaProcessual();
		this.popularComboComarca();
		this.popularComboFaseProcesso();
		this.popularComboForo();
		this.popularComboInstancia();
		this.popularComboRito();
		this.popularComboSituacaoProcesso();
		this.popularComboTipoAcao();
		this.popularComboVara();
	}
	
	public void adicionar() {
		Integer sequenciaProcesso = processoLogica.obterProximoProcesso();
		Integer anoAtual = DataUtil.obterAnoAtual();
		
		processo.setSequenciaProcesso(sequenciaProcesso);
		processo.setAnoProcesso(anoAtual);

		try {
			if (validaCampos()) {
				logicaProcesso.adicionar(processo);
				adicionarMensagem("Processo adicionado com sucesso");
				this.buscarProcesso();
				//fecharModal("dialogProcesso");
			} else {
				return;
			}
			
		} catch (Exception e) {
			adicionarMensagem("Houve um erro ao adicionar o Processo");
		}
	}
	
	public void prepararAdicionar() {
		this.processo = new Processo();
		abrirModal("dialogProcesso");
	}
	
	public void selecionarRegistro(Long idProcesso, String operacao) {
		try {
			this.processo = logicaProcesso.obterPorId(Processo.class, idProcesso);
			
			if (operacao.equalsIgnoreCase("EDITAR")) {
				abrirModal("dialogProcesso");
			} else if (operacao.equalsIgnoreCase("EXCLUIR")){
				abrirModal("dialogExcluir");
			} else {
				abrirModal("dialogArquivar");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void editar() {
		try {
			if (validaCampos()) {
				logicaProcesso.editar(this.processo);
				adicionarMensagem("Processo editado com sucesso");
				fecharModal("dialogProcesso");
				this.buscarProcesso();
			} else {
				return;
			}
			
		} catch (Exception e) {
			adicionarMensagem("Houve um erro ao editar o Processo");
		}
	}
	
	public void remover() {
		try {
			logicaProcesso.remover(Processo.class, this.processo.getId());
			adicionarMensagem("Processo removido com sucesso");
			fecharModal("dialogExcluir");
			this.buscarProcesso();
		} catch (Exception e) {
			adicionarMensagem("Houve um erro ao remover o Processo");
		}
	}
	
	public void arquivar() {
		try {
			this.processo.setArquivoMorto(true);
			logicaProcesso.editar(this.processo);
			adicionarMensagem("Processo arquivado com sucesso");
			fecharModal("dialogArquivar");
			this.buscarProcesso();
		} catch (Exception e) {
			adicionarMensagem("Houve um erro ao remover o Processo");
		}
	}
	
	public void buscarProcesso() {
		if (listaProcesso != null) {
			this.listaProcesso.clear();
		}
		
		try {
			if (!StringUtil.textoPreenchido(numeroProcesso)) {
				this.listaProcesso =  processoLogica.buscarTodosProcessos();
			} else {
//				this.listaProcesso = logicaProcesso.buscarPorCampo(Processo.class, "nome", nomeProcesso);
			}
		} catch (Exception e) {
			adicionarMensagem("Houve um erro ao buscar as informações");
		}
	}
	
	public boolean validaCampos() {
		boolean valido = true;
		
		if (!StringUtil.textoPreenchido(this.processo.getNumeroProcesso())) {
			adicionarMensagem("O campo número do processo é obrigatório");
			valido = false;
		}
		return valido;
	}
	
	public void popularComboTipoAcao() {
		if (listaTipoAcao != null) {
			listaTipoAcao.clear();
		}
		try {
			this.listaTipoAcao = logicaTipoAcao.buscarTodos(TipoAcao.class, "acao");
		} catch (Exception e) {
			System.out.println("Erro ao buscar os tipos de ação");
		}
	}
	
	public void popularComboVara() {
		if (listaVara != null) {
			listaVara.clear();
		}
		try {
			this.listaVara = logicaVara.buscarTodos(Vara.class, "vara");
		} catch (Exception e) {
			System.out.println("Erro ao buscar as varas");
		}
	}
	
	public void popularComboComarca() {
		if (listaComarca != null) {
			listaComarca.clear();
		}
		try {
			this.listaComarca = logicaComarca.buscarTodos(Comarca.class, "numeroComarca");
		} catch (Exception e) {
			System.out.println("Erro ao buscar as comarcas");
		}
	}
	
	public void popularComboRito() {
		if (listaRito != null) {
			listaRito.clear();
		}
		try {
			this.listaRito = logicaRito.buscarTodos(Rito.class, "rito");
		} catch (Exception e) {
			System.out.println("Erro ao buscar as comarcas");
		}
	}
	
	public void popularComboForo() {
		if (listaForo != null) {
			listaForo.clear();
		}
		try {
			this.listaForo = logicaForo.buscarTodos(Foro.class, "nome");
		} catch (Exception e) {
			System.out.println("Erro ao buscar os foros");
		}
	}
	
	public void popularComboAreaProcessual() {
		if (listaAreaProcessual != null) {
			listaAreaProcessual.clear();
		}
		try {
			this.listaAreaProcessual = logicaAreaProcessual.buscarTodos(AreaProcessual.class, "area");
		} catch (Exception e) {
			System.out.println("Erro ao buscar as áreas processuais");
		}
	}
	
	public void popularComboFaseProcesso() {
		if (listaFaseProcesso != null) {
			listaFaseProcesso.clear();
		}
		try {
			this.listaFaseProcesso = logicaFaseProcesso.buscarTodos(FaseProcesso.class, "fase");
		} catch (Exception e) {
			System.out.println("Erro ao buscar as fases do processo");
		}
	}
	
	public void popularComboSituacaoProcesso() {
		if (listaSituacaoProcesso != null) {
			listaSituacaoProcesso.clear();
		}
		try {
			this.listaSituacaoProcesso = logicaSituacaoProcesso.buscarTodos(SituacaoProcesso.class, "situacao");
		} catch (Exception e) {
			System.out.println("Erro ao buscar as situações do processo");
		}
	}
	
	public void popularComboInstancia() {
		if (listaInstancia != null) {
			listaInstancia.clear();
		}
		try {
			this.listaInstancia = logicaInstancia.buscarTodos(Instancia.class, "instancia");
		} catch (Exception e) {
			System.out.println("Erro ao buscar as instâncias do processo");
		}
	}

	public Processo getProcesso() {
		return processo;
	}

	public void setProcesso(Processo processo) {
		this.processo = processo;
	}

	public List<Processo> getListaProcesso() {
		return listaProcesso;
	}

	public void setListaProcesso(List<Processo> listaProcesso) {
		this.listaProcesso = listaProcesso;
	}

	public List<TipoAcao> getListaTipoAcao() {
		return listaTipoAcao;
	}

	public void setListaTipoAcao(List<TipoAcao> listaTipoAcao) {
		this.listaTipoAcao = listaTipoAcao;
	}

	public List<Vara> getListaVara() {
		return listaVara;
	}

	public void setListaVara(List<Vara> listaVara) {
		this.listaVara = listaVara;
	}

	public List<Comarca> getListaComarca() {
		return listaComarca;
	}

	public void setListaComarca(List<Comarca> listaComarca) {
		this.listaComarca = listaComarca;
	}

	public List<Rito> getListaRito() {
		return listaRito;
	}

	public void setListaRito(List<Rito> listaRito) {
		this.listaRito = listaRito;
	}

	public List<Foro> getListaForo() {
		return listaForo;
	}

	public void setListaForo(List<Foro> listaForo) {
		this.listaForo = listaForo;
	}

	public List<AreaProcessual> getListaAreaProcessual() {
		return listaAreaProcessual;
	}

	public void setListaAreaProcessual(List<AreaProcessual> listaAreaProcessual) {
		this.listaAreaProcessual = listaAreaProcessual;
	}

	public List<FaseProcesso> getListaFaseProcesso() {
		return listaFaseProcesso;
	}

	public void setListaFaseProcesso(List<FaseProcesso> listaFaseProcesso) {
		this.listaFaseProcesso = listaFaseProcesso;
	}

	public List<SituacaoProcesso> getListaSituacaoProcesso() {
		return listaSituacaoProcesso;
	}

	public void setListaSituacaoProcesso(
			List<SituacaoProcesso> listaSituacaoProcesso) {
		this.listaSituacaoProcesso = listaSituacaoProcesso;
	}

	public List<Instancia> getListaInstancia() {
		return listaInstancia;
	}

	public void setListaInstancia(List<Instancia> listaInstancia) {
		this.listaInstancia = listaInstancia;
	}

	public String getNumeroProcesso() {
		return numeroProcesso;
	}

	public void setNumeroProcesso(String numeroProcesso) {
		this.numeroProcesso = numeroProcesso;
	}

	public void setLogicaProcesso(DefaultLogicaContract<Processo> logicaProcesso) {
		this.logicaProcesso = logicaProcesso;
	}

	public void setLogicaTipoAcao(DefaultLogicaContract<TipoAcao> logicaTipoAcao) {
		this.logicaTipoAcao = logicaTipoAcao;
	}

	public void setLogicaVara(DefaultLogicaContract<Vara> logicaVara) {
		this.logicaVara = logicaVara;
	}

	public void setLogicaComarca(DefaultLogicaContract<Comarca> logicaComarca) {
		this.logicaComarca = logicaComarca;
	}

	public void setLogicaRito(DefaultLogicaContract<Rito> logicaRito) {
		this.logicaRito = logicaRito;
	}

	public void setLogicaForo(DefaultLogicaContract<Foro> logicaForo) {
		this.logicaForo = logicaForo;
	}

	public void setLogicaAreaProcessual(DefaultLogicaContract<AreaProcessual> logicaAreaProcessual) {
		this.logicaAreaProcessual = logicaAreaProcessual;
	}

	public void setLogicaFaseProcesso(DefaultLogicaContract<FaseProcesso> logicaFaseProcesso) {
		this.logicaFaseProcesso = logicaFaseProcesso;
	}

	public void setLogicaSituacaoProcesso(DefaultLogicaContract<SituacaoProcesso> logicaSituacaoProcesso) {
		this.logicaSituacaoProcesso = logicaSituacaoProcesso;
	}

	public void setLogicaInstancia(DefaultLogicaContract<Instancia> logicaInstancia) {
		this.logicaInstancia = logicaInstancia;
	}

	public void setProcessoLogica(ProcessoLogicaContract processoLogica) {
		this.processoLogica = processoLogica;
	}
	
	
}